﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Xml.Serialization;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace WIAssistant
{
    public delegate void BeforeMovedWorkItemSave(WorkItem workItem, WorkItemTypeMapping mapping);
    public class MoveWorkItemsCommand
    {
        // This is the actual move command.  It gets called from the GUI.
        public SimpleCommand MoveWorkItems { get; set; }

        private readonly MainMediator _vm;

        private BackgroundWorker _moveInBackground;

        public MoveWorkItemsCommand(MainMediator vm)
        {
            _vm = vm;
            MoveWorkItems = new SimpleCommand
                                {
                                    ExecuteDelegate = x => MoveButtonClicked(x),
                                    CanExecuteDelegate = x => CanMoveButtonExecute(x)
                                };

            _moveInBackground = new BackgroundWorker();
            _moveInBackground.DoWork += MoveWorkItemsDoWork;
            _moveInBackground.ProgressChanged += MoveWorkItemsProgressChanged;
            _moveInBackground.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;
            _moveInBackground.WorkerReportsProgress = true;

        }

        private void MoveWorkItemsProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            WorkItem workItem = (WorkItem) e.UserState;
            _vm.WaitCursorMessage("Moving " + workItem.GetDefaultColumnValue());
        }


        // When the <see cref="WorkItems"/> have been moved then this is called.
        private void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _vm.EndWaitCursor();
        }

        // This actually moves the workitems
        private static void MoveWorkItemsDoWork(object sender, DoWorkEventArgs e)
        {
            MainMediator vm = (MainMediator) e.Argument;
            //// Get the stuff from the gui thread that we will need
            // Get the mappings
            ObservableCollection<WorkItemTypeMapping> workItemTypeMappings = null;
            vm.Dispatcher.Invoke(new Action(() => workItemTypeMappings = vm.WorkItemTypeMappings));
            // Get the pad
            Dictionary<WorkItem, Canvas> pad = null;
            vm.Dispatcher.Invoke(new Action(() => pad = vm.Pad));
            // Get the selected Iteration
            IterationNode selectedIterationNode = null;
            vm.Dispatcher.Invoke(new Action(() => selectedIterationNode = vm.SelectedIterationNode));

            IMain formUI = null;
            vm.Dispatcher.Invoke(new Action(() => formUI = vm.Form));

            // Get the BackgroundWorker that raised this event.
            BackgroundWorker worker = sender as BackgroundWorker;

            MoveWorkItem moveWorkItem = new MoveWorkItem();
            moveWorkItem.MoveAllWorkItems(workItemTypeMappings, pad, selectedIterationNode, formUI, worker);

            // Refresh the query results
            vm.Dispatcher.Invoke(new Action(() => vm.RunQuery(vm.CurrentQuery)));
        }

        private bool CanMoveButtonExecute(object sender)
        {
            if (_vm.SelectedIterationNode != null)
                return true;
            else
                return false;
        }



        private void MoveButtonClicked(object sender)
        {
            _vm.StartWaitCursor();
            _moveInBackground.RunWorkerAsync(_vm);
        }


    }
}
